/*
 * comlan
 */

package com.promfy.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;



import android.util.Log;
/**
 * there's kinds of  method to runtime shell in java
 * 
 * @author mfy
 *
 */
public class ShellUtil {
	private static final String TAG = "shell";

	/**
	 * path = dir + filename
	 * 
	 * @throws IOException
	 */
	private  void chmodDir(String path) throws Exception {
		int index = path.lastIndexOf('/');
		if (index == -1) {
			return;
		}
		String p = path.substring(0, index);
		String[] args = { "chmod", "705", p };

		Process proc = null;
		proc = Runtime.getRuntime().exec(args);
		Log.d(TAG, "chmod 2");
		StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "Error");        
        StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "Input");
        errorGobbler.start();
        outputGobbler.start();
        proc.waitFor();
		chmodDir(p); 
	} 
 
	private  void chmodFile(String path) throws Exception { 
		String args = "chmod 705 " + path;
		Log.d(TAG, "args = " + args);  
		Process proc = Runtime.getRuntime().exec(args);
		Log.d(TAG, "chmod 3");   
		StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "Error");        
        StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "Input");
        errorGobbler.start(); 
        outputGobbler.start();
        proc.waitFor();      
//		chmod(args);  
	} 
     
	private void chmod(String... commands){
		Process process = null;
		try {
			process = new ProcessBuilder()       
				.command("/system/bin/sh")        
				.redirectErrorStream(true)
				.start();
			DataOutputStream os = new DataOutputStream(process.getOutputStream());
			
			for (String single : commands) {
			   os.writeBytes(single + "\n");
			   Log.d(TAG, "Issue command: " + single);
			   os.flush();
			} 
			os.writeBytes("exit\n"); 
			os.flush();
		    BufferedReader reader = new BufferedReader(
		            new InputStreamReader(process.getInputStream()));
		    int read;
		    char[] buffer = new char[4096];
		    StringBuffer output = new StringBuffer();
		    while ((read = reader.read(buffer)) > 0) {
		        output.append(buffer, 0, read); 
		    }
		    reader.close(); 
		    int exitCode = process.waitFor();
		    String s = output.toString();
		    Log.d("wget", "wget exit code:" + exitCode);
		    Log.d("wget", "wget returns: \n" + s);
		    
		}  
		catch (Exception e) {
		    e.printStackTrace();
		}
		finally {
			if(process != null)
				process.destroy();
		}

	}
	
	/**
	 * path = dir + filename;
	 * 
	 * @param path
	 * @throws IOException   
	 */ 
	public  void chmodPath(String path) throws Exception {
		String[] args = { "chmod", "604", path };
		//Log.d(TAG, "chmod file before exec()");
		//Log.d(TAG, "chmodDir() path = " + path);
		Process proc = Runtime.getRuntime().exec(args);
		Log.d(TAG, "chmod 1");

		StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "Error");        
        StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "Input");
        errorGobbler.start();
        outputGobbler.start();
        proc.waitFor();
		Log.d(TAG, "chmod 11");

		do_exec("chmod 604 "+ path);
		//Log.d(TAG, "chmod file after exec()");
		chmodDir(path);
	}

	/**
	 * execute shell command
	 * @param cmd
	 * @return 
	 * @throws Exception
	 */
	public  int shell(String cmd) throws Exception {
		Process proc = Runtime.getRuntime().exec(cmd);
		StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "Error");        
        StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "Input");
        errorGobbler.start();
        outputGobbler.start();
        proc.waitFor();
        return proc.exitValue();
	}
	
//	public class StreamGobbler extends Thread {
//		InputStream is;
//		String type;
//
//		StreamGobbler(InputStream is, String type) {
//			this.is = is;
//			this.type = type;
//		}
//		@Override
//		public void run() {
//			InputStreamReader isr = null;
//			BufferedReader br = null;
//			try {
//				isr = new InputStreamReader(is);
//				br = new BufferedReader(isr);
//				String line = null;
//				while ((line = br.readLine()) != null) {
//					if (type.equals("Error")){	
//						Log.d(TAG, "chmod Error = " + line);
//						System.out.println("chmod Error = " + line);
//						System.out.flush();
//					}
//					else{
//						Log.d(TAG, "chmod Input = " + line);
//						System.out.println("chmod Input = " + line);
//						System.out.flush();
//					}
//				}
//			} catch (IOException ioe) {
//				ioe.printStackTrace();
//			}finally{
//				if(isr != null){
//					try {
//						isr.close();
//					} catch (IOException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//				}
//				if(br != null){
//					try {
//						br.close();
//					} catch (IOException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//				}
//			}
//		}
//	}

	/**
	 * you must set buf big enough, in roder to read results just one time.
	 * otherwise it will block 
	 */
	public class StreamGobbler extends Thread {
		
		InputStream is;
		String type;
		String info;
		
		public String getInfo() {
			return info;
		}
		StreamGobbler(InputStream is, String type) {
			this.is = is;
			this.type = type;  
		}

		@Override
		public void run() {
			InputStreamReader isr = null;
			BufferedReader br = null;
			try {
				isr = new InputStreamReader(is);
				br = new BufferedReader(isr);
				int len;
				char[] buf = new char[1024 *10];
				StringBuffer sb = new StringBuffer();
				while ((len = br.read(buf)) != -1) {
					sb.append(buf,0,len);
				}
				if(sb!=null && sb.toString().trim().length()!=0){
					if (type.equals("Error")){	
						Log.d(TAG, "Error = " + sb);
					}
					else {  
						Log.d(TAG, "Input = " + sb);
					}
				}
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}finally{
				if(isr != null){
					try {
						isr.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(br != null){
					try {
						br.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	
	
	public static String  do_exec(String cmd) {
		String s = "\n";
		try {
			Process p = Runtime.getRuntime().exec(cmd);
			BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String line = null;
			while ((line = in.readLine()) != null) {
				s += line + "\n";
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//text.setText(s);
		return cmd;
	}
}
